package com.dingreading.cloud.app.controller;

import com.alibaba.fastjson.JSONObject;
import com.dingreading.cloud.app.entity.*;
import com.dingreading.cloud.app.service.*;
import com.dingreading.cloud.app.util.UidUtil;
import com.dingreading.cloud.common.base.R;
import com.dingreading.cloud.common.dto.AppStaffDto;
import com.dingreading.cloud.common.util.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/app/store/")
@Api(tags = "APP-门店管理")
public class AppStoreController {

    @Resource
    private StaffService staffService;
    @Resource
    private StoresService storesService;
    @Resource
    private StaffRolesService staffRolesService;
    @Resource
    private StoreAndroidService storeAndroidService;
    @Resource
    private AppVersionService appVersionService;
    @Resource
    private CorporationsService corporationsService;
    @Resource
    private StoreAndroidLocationService androidLocationService;

    @ApiOperation(value = "app检查版本更新")
    @PostMapping(value = "/checkNewVersion", produces = "application/json; charset=UTF-8")
    public R<Object> checkNewVersion(
            HttpServletRequest request,
            @ApiParam(value = "手机系统 1.安卓 2.ios") @RequestParam(value = "os", required = false) Integer os,
            @ApiParam(value = "设备标识") @RequestParam(value = "deviceId", required = false) String deviceId,
            @ApiParam(value = "版本号") @RequestParam(value = "versionCode", required = false) Integer versionCode,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid", required = false) String storeUid,
            @ApiParam(value = "定位地址") @RequestParam(value = "address", required = false) String address,
            @ApiParam(value = "经度") @RequestParam(value = "lng", required = false) String lng,
            @ApiParam(value = "纬度") @RequestParam(value = "lat", required = false) String lat
    ) {
        if (StringUtils.isNotBlank(storeUid)) {
            Stores stores = storesService.getByUid(storeUid);
            // 判读是否是自营门店
            if (stores == null)
                return R.fail("未查询到门店");

            // 每日更新门店设备定位信息
            String ip = IpUtil.getIpAddr(request);
            if (StringUtils.isNotBlank(address) && StringUtils.isNotBlank(deviceId) && StringUtils.isNotBlank(lng) && StringUtils.isNotBlank(lat))
                updateLocationInf(storeUid, stores.getStoreName(), deviceId, address, lng, lat, ip);

            if (versionCode != null) {
                if (StringUtils.isBlank(stores.getCorpUid()))
                    return R.fail("公司标识获取失败");
                if (versionCode <= 0)
                    return R.fail("版本号错误" + versionCode);

                boolean selfStatus = AccountUtil.isSelfStore(stores.getOperationType());

                List<AppVersion> list = appVersionService.getMaxCodeByOsAndVersionCode(1, versionCode, selfStatus);
                if (CollectionUtils.isNotEmpty(list))
                    return R.ok(list.get(0));
            }
        }

        return R.ok();
    }

    /**
     * 每日更新门店设备定位信息
     */
    private void updateLocationInf(String storeUid, String storeName, String deviceId, String address, String lng, String lat, String ip) {
        String ymd = DateUtil.getNowDateStr();
        long cnt = androidLocationService.haveLocationInfo(storeUid, deviceId, ymd, address, lng, lat);
        if (cnt <= 0) {
            // 获取1公里范围内的除本门店的附近门店
            double kilometers = 1d;
            Map<String, Double> map = TencentMapUtil.getFourPoint(lng, lat, kilometers);
            String latitudeMin = map.get("latitudeMin").toString();
            String latitudeMax = map.get("latitudeMax").toString();
            String longitudeMin = map.get("longitudeMin").toString();
            String longitudeMax = map.get("longitudeMax").toString();

            // 1公里误差内有门店设备的经纬度记录，只更新时间
            List<Long> locationList = androidLocationService.getNearProtects(storeUid, deviceId, ymd,
                    longitudeMin, longitudeMax, latitudeMin, latitudeMax);
            if (CollectionUtils.isEmpty(locationList)) {
                StoreAndroidLocation location = new StoreAndroidLocation();
                location.setStoreUid(storeUid);
                location.setStoreName(storeName);
                location.setDeviceId(deviceId);
                location.setAddress(address);
                location.setLng(lng);
                location.setLat(lat);
                location.setIp(ip);
                androidLocationService.saveOrUpdate(location);
            } else {
                androidLocationService.updateInfo(storeUid, storeName, deviceId, ymd, ip);
            }
        } else {
            androidLocationService.updateInfo(storeUid, storeName, deviceId, ymd, ip);
        }
    }

    @ApiOperation(value = "app获取员工的所在门店")
    @PostMapping(value = "/getStaffStores", produces = "application/json; charset=UTF-8")
    public R<Object> getStaffStores(
            @ApiParam(value = "手机系统 1.安卓 2.ios") @RequestParam(value = "os") Integer os,
            @ApiParam(value = "设备标识") @RequestParam(value = "deviceId") String deviceId,
            @ApiParam(value = "版本号") @RequestParam(value = "versionCode") Integer versionCode,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid", required = false) String storeUid,
            @ApiParam(value = "店长账号") @RequestParam(value = "username") String username
    ) {
        Staff staff = staffService.getByUsername(username);
        if (null == staff)
            return R.fail("员工账号获取失败");
        if (!staff.getEnabled().equals(1))
            return R.fail("员工已被禁用");

        List<JSONObject> storeList = staffRolesService.getByStoreManagerList(staff.getUid());
        if (CollectionUtils.isNotEmpty(storeList))
            return R.ok(storeList);
        return R.ok();
    }


    @ApiOperation(value = "签到app店员登录")
    @PostMapping(value = "/login", produces = "application/json; charset=UTF-8")
    public R<Object> login(
            HttpServletRequest request,
            @ApiParam(value = "手机系统 1.安卓 2.ios") @RequestParam(value = "os") Integer os,
            @ApiParam(value = "设备标识") @RequestParam(value = "deviceId") String deviceId,
            @ApiParam(value = "版本号") @RequestParam(value = "versionCode") Integer versionCode,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "账号") @RequestParam(value = "username") String username,
            @ApiParam(value = "密码") @RequestParam(value = "password") String password
    ) {
        if (StringUtils.isBlank(username) || StringUtils.isBlank(password))
            return R.fail("账号或密码错误");
        if (StringUtils.isBlank(deviceId))
            return R.fail("设备标识错误");

        Staff staff = staffService.getByUsername(username);
        if (null == staff)
            return R.fail("员工账号获取失败");
        if (!staff.getEnabled().equals(1))
            return R.fail("员工已被禁用");

        String pwdSource = StaffPwdUtil.getPwdSource(password, staff.getPwdSalt());
        String encodedPwd = MD5Util.MD5Encode(pwdSource);
        if (!encodedPwd.equals(staff.getEncodedPwd()))
            return R.fail("密码错误");

        Corporations corporations = corporationsService.getByUid(staff.getCorpUid());
        String judgeCorp = UidUtil.judgeCorp(corporations);
        if (StringUtils.isNotBlank(judgeCorp))
            return R.fail(judgeCorp);

        Stores stores = storesService.getByUid(storeUid);
        if (null == stores)
            return R.fail("门店信息获取失败");
        if (!stores.getEnabled().equals(1))
            return R.fail("门店已被禁用");

        // 请求的IP
        String ip = IpUtil.getIpAddr(request);
        Date time = DateUtil.getNowDatetime();
        // 门店绑定设备标识
        long cnt = storeAndroidService.getByStoreUidAndDeviceIdCnt(storeUid, deviceId);
        if (cnt <= 0) {
            StoreAndroid android = new StoreAndroid();
            android.setStoreUid(storeUid);
            android.setStoreName(stores.getStoreName());
            android.setEnabled(1);
            android.setDeviceId(deviceId);
            android.setVersionCode(versionCode);
            android.setIp(ip);
            android.setLoginTime(time);
            storeAndroidService.saveOrUpdate(android);
        } else {
            storeAndroidService.updateInfo(storeUid, stores.getStoreName(), deviceId, versionCode, ip, time);
        }

        AppStaffDto data = new AppStaffDto();
        data.setUid(staff.getUid());
        data.setNickName(staff.getNickName());
        data.setFullName(staff.getFullName());
        data.setPubPhone(staff.getPubPhone());
        data.setPriPhone(staff.getPriPhone());
        data.setDepartment(staff.getDepartment());
        data.setRole(staff.getRole());
        data.setEnabled(staff.getEnabled());
        data.setStoreUid(storeUid);
        data.setStoreName(stores.getStoreName());

        return R.ok(data);
    }

    @ApiOperation(value = "检查新版本并登录")
    @PostMapping(value = "/checkVersionAndLogin", produces = "application/json; charset=UTF-8")
    public R<Object> checkVersionAndLogin(
            HttpServletRequest request,
            @ApiParam(value = "手机系统 1.安卓 2.ios") @RequestParam(value = "os") Integer os,
            @ApiParam(value = "设备标识") @RequestParam(value = "deviceId") String deviceId,
            @ApiParam(value = "版本号") @RequestParam(value = "versionCode") Integer versionCode,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "账号") @RequestParam(value = "username") String username,
            @ApiParam(value = "密码") @RequestParam(value = "password") String password,
            @ApiParam(value = "定位地址") @RequestParam(value = "address", required = false) String address,
            @ApiParam(value = "经度") @RequestParam(value = "lng", required = false) String lng,
            @ApiParam(value = "纬度") @RequestParam(value = "lat", required = false) String lat
    ) {
        if (StringUtils.isBlank(username) || StringUtils.isBlank(password))
            return R.fail("账号或密码错误");
        if (StringUtils.isBlank(deviceId))
            return R.fail("设备标识错误");

        Staff staff = staffService.getByUsername(username);
        if (null == staff)
            return R.fail("员工账号获取失败");
        if (!staff.getEnabled().equals(1))
            return R.fail("员工已被禁用");

        String pwdSource = StaffPwdUtil.getPwdSource(password, staff.getPwdSalt());
        String encodedPwd = MD5Util.MD5Encode(pwdSource);
        if (!encodedPwd.equals(staff.getEncodedPwd()))
            return R.fail("密码错误");

        Corporations corporations = corporationsService.getByUid(staff.getCorpUid());
        String judgeCorp = UidUtil.judgeCorp(corporations);
        if (StringUtils.isNotBlank(judgeCorp))
            return R.fail(judgeCorp);

        Stores stores = storesService.getByUid(storeUid);
        if (null == stores)
            return R.fail("门店信息获取失败");
        if (!stores.getEnabled().equals(1))
            return R.fail("门店已被禁用");
        if (StringUtils.isBlank(stores.getCorpUid()))
            return R.fail("公司标识获取失败");

        JSONObject jsonObject = new JSONObject();
        // 检查新版本
        if (versionCode == null || versionCode <= 0)
            return R.fail("版本号错误" + versionCode);
        boolean selfStatus = AccountUtil.isSelfStore(stores.getOperationType());
        List<AppVersion> list = appVersionService.getMaxCodeByOsAndVersionCode(1, versionCode, selfStatus);
        if (CollectionUtils.isNotEmpty(list)) {
            jsonObject.put("app", list.get(0));
            return R.ok(jsonObject);
        }

        // 每日更新门店设备定位信息
        String ip = IpUtil.getIpAddr(request);
        if (StringUtils.isNotBlank(address) && StringUtils.isNotBlank(deviceId) && StringUtils.isNotBlank(lng) && StringUtils.isNotBlank(lat))
            updateLocationInf(storeUid, stores.getStoreName(), deviceId, address, lng, lat, ip);
        // 请求的IP
        Date time = DateUtil.getNowDatetime();
        // 门店绑定设备标识
        long cnt = storeAndroidService.getByStoreUidAndDeviceIdCnt(storeUid, deviceId);
        if (cnt <= 0) {
            StoreAndroid android = new StoreAndroid();
            android.setStoreUid(storeUid);
            android.setStoreName(stores.getStoreName());
            android.setEnabled(1);
            android.setDeviceId(deviceId);
            android.setVersionCode(versionCode);
            android.setIp(ip);
            android.setLoginTime(time);
            storeAndroidService.saveOrUpdate(android);
        } else {
            storeAndroidService.updateInfo(storeUid, stores.getStoreName(), deviceId, versionCode, ip, time);
        }

        // 账号信息
        AppStaffDto staffDto = new AppStaffDto();
        staffDto.setUid(staff.getUid());
        staffDto.setNickName(staff.getNickName());
        staffDto.setFullName(staff.getFullName());
        staffDto.setPubPhone(staff.getPubPhone());
        staffDto.setPriPhone(staff.getPriPhone());
        staffDto.setDepartment(staff.getDepartment());
        staffDto.setRole(staff.getRole());
        staffDto.setEnabled(staff.getEnabled());
        staffDto.setStoreUid(storeUid);
        staffDto.setStoreName(stores.getStoreName());
        jsonObject.put("staff", staffDto);

        return R.ok(jsonObject);
    }

}